/*********************************************************************************
 *      Copyright:  (C) 2022 dairongan<2974932606@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  socket.c
 *    Description:  This file socket.c
 *    域名解析以及socket连接             
 *        Version:  1.0.0(22/04/22)
 *         Author:  dairongan <2974932606@qq.com>
 *      ChangeLog:  1, Release initial version on "22/04/22 21:30:29"
 *                 
 ********************************************************************************/
#include <sys/types.h>     
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include "logger.h"
#include "sqlaction.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

int socket_connect_server(struct sockaddr_in serv_addr,int port,char *serv_ip)
{
	int     					flag=-1;
	int     					sock_fd=-1;
	char						buf[128];
    struct hostent              *getname=NULL;
	char						*ptr=NULL;
	char						**pptr=NULL;
	struct in_addr				inaddr;
    //如果不是IP地址那就域名解析
    if(!inet_aton(serv_ip,&inaddr))
    {
        getname = gethostbyname(serv_ip);
        if(getname == NULL)
        {
            log_error("Get host_alias failure:%s\n",strerror(errno));
            return -1;
        }

        memset(buf,0,sizeof(buf));
        pptr = getname->h_addr_list;
        if(NULL == (ptr = inet_ntop(getname->h_addrtype,*pptr,buf,sizeof(buf))))
        {
            log_error("failure:%s\n",strerror(errno));
            return -2;
        }
		memcpy(serv_ip,ptr,32);
    }
	sock_fd = socket(AF_INET,SOCK_STREAM,0);
	if(sock_fd < 0)
	{
		log_error("Create socket failure:%s\n",strerror(errno));
		return -3;
	}

	memset(&serv_addr,0,sizeof(serv_addr));
	serv_addr.sin_family=AF_INET;
	serv_addr.sin_port=htons(port);
	inet_aton(serv_ip,&serv_addr.sin_addr);
	flag = connect(sock_fd,(const struct sockaddr *)&serv_addr,sizeof(serv_addr));
	if(flag < 0)
	{
		socket_term(&sock_fd);
		return -4;
	}
	return sock_fd;
}

int socket_start_server(int serv_port,char *serv_ip)
{
        struct sockaddr_in              servaddr;
        int                             sockfd=-1;
        int                             rv=0;
        int                             on=1;

        memset(&servaddr,0,sizeof(servaddr));
        servaddr.sin_family=AF_INET;
        servaddr.sin_port=htons(serv_port);

        sockfd = socket(AF_INET,SOCK_STREAM,0);
        if(sockfd < 0)
        {
                log_error("Create socket failure:%s\n",strerror(errno));
                rv = -1;
                goto CleanUp;
        }
        log_info("Create socket[%d] successfully\n",sockfd);

        if(!serv_port)//一个服务器端口不可能为空
        {
                log_error("server'listen_port is empty\n");
                rv = -2;
                goto CleanUp;
        }
        if(!serv_ip)
        {
                servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        }
        else
        {
                if(inet_pton(AF_INET,serv_ip,&servaddr.sin_addr)<0)
                {
                        log_error("inet_pton() failure:%s\n",strerror(errno));
                        rv = -3;
                        goto CleanUp;
                }
        }
        if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))<0)
        {
                log_error("setsockopt failure:%s\n",strerror(errno));
                rv = -4;
                goto CleanUp;
        }

        if(bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr))<0)
        {
                log_error("socket[%d] bind on port[%d] failure:%s\n",sockfd,
                                serv_port,strerror(errno));
                rv = -5;
                goto CleanUp;
        }

        if(listen(sockfd,13)<0)
        {
            	log_error("listen() failure:%s\n",strerror(errno));
                rv = -6;
                goto CleanUp;
        }

CleanUp:
        if(rv < 0)
                socket_term(&sockfd);
        else
                rv = sockfd;
        return rv;
}

int socket_term(int *sockfd)
{
	if(NULL==sockfd)
	{
		return -1;
	}
	if(*sockfd>0)
	{
		close(*sockfd);
		*sockfd=-1;
	}
	return 1;
}
int socket_write(int *sockfd,char *buf,int len)
{
	int rv=0;

	rv = write(*sockfd,buf,len);
    if(rv<0)
	{
		log_error("write failure:%s\n",strerror(errno));
		socket_term(sockfd);
		return -1;
	}
	return 1;
}

int socket_read_divideinfo(int *sockfd,char *buf,info_temp_t *infor)
{
	char buf1[128];
	char *mark="/";
	int rv = 0;
	char	*sn,*time,*temp;

	memset(buf,0,sizeof(buf));
	rv = read(*sockfd,buf,33);
	if(rv <= 0)
	{
		 log_error("read failure:%s\n",strerror(errno));
		 socket_term(sockfd);
		 return -1;
	}
	else
	{
		memset(buf1,0,sizeof(buf1));
		strncpy(buf1,buf,128);
		sn=strtok(buf1,mark);
		time=strtok(NULL,mark);
		temp=strtok(NULL,mark);
	
		memset(infor->prod_id,0,8);
		memset(infor->ttime,0,32);
		memset(infor->temp,0,8);
		strncpy(infor->prod_id,sn,strlen(sn));
		strncpy(infor->ttime,time,strlen(time));
		strncpy(infor->temp,temp,strlen(temp));
	}

	return 1;
}

int socket_check_connect(int sockfd)
{
	struct tcp_info infor;
	int				len=sizeof(infor);

	if(sockfd<0)
		return -1;
	
	getsockopt(sockfd,IPPROTO_TCP,TCP_INFO,&infor,(socklen_t *)&len);
	if(infor.tcpi_state==TCP_ESTABLISHED)//没断开
	{
		return 1;
	}
	else
	{
		return -2;	
	}
}

